//
//  SJQRCodeViewController.swift
//  SJWeiboSwift
//
//  Created by app;e on 15/10/5.
//  Copyright © 2015年 world. All rights reserved.
//
//  二维码扫描界面

import UIKit
import AVFoundation

class SJQRCodeViewController: UIViewController,UITabBarDelegate,AVCaptureMetadataOutputObjectsDelegate {
   
   ///扫描结果
    @IBOutlet weak var resultLabel: UILabel!
    ///冲击波
    @IBOutlet weak var scanImage: UIImageView!
    ///高度约束
    @IBOutlet weak var heightConstraint: NSLayoutConstraint!
    ///宽度约束
    @IBOutlet weak var widthConstraint: NSLayoutConstraint!
    ///冲击波顶部约束
    @IBOutlet weak var topConstraint: NSLayoutConstraint!
    @IBOutlet weak var tabBar: UITabBar!
    
    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        startAnimation()
        
        satrtScan()
    }
    ///冲击波动画
    func startAnimation(){
        topConstraint.constant = -heightConstraint.constant
        view.layoutIfNeeded()
        
        UIView.animateWithDuration(2.0, animations: { () -> Void in
            //让动画重复执行(注意必须要在block里面设置)
            UIView.setAnimationRepeatCount(MAXFLOAT)
            self.topConstraint.constant = self.heightConstraint.constant
            self.view.layoutIfNeeded()
            }, completion: nil)

    }
    
    ///显示我的名片
    @IBAction func showMyQRCode(sender: AnyObject) {
        navigationController?.pushViewController(SJMyQRCodeViewController(), animated: true)
    }
    
    ///关闭当前控制器
    @IBAction func close(sender: AnyObject) {
        
        dismissViewControllerAnimated(true, completion: nil)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tabBar.delegate = self
        //默认选中第0个
        tabBar.selectedItem = tabBar.items![0]
        
        //设置二维码扫描环境
        setupSession()
        setupLayers()
    }
    
    // MARK:- tabBar的代理
    func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
        //设置扫描区域的高度: 二维码 * 1  / 条形码 *0.5
        heightConstraint.constant = widthConstraint.constant * (item.tag == 0 ? 1.0 : 0.5)
        
        //移除切换之前的动画
        scanImage.layer.removeAllAnimations()
        //重新开始动画
        startAnimation()
    }

    // MARK: - 二维码
    ///开始扫描
    func satrtScan(){
        session.startRunning()
    }
    
    ///设置图层
    func setupLayers(){
        //1.设置绘图图层
        drawLayer.frame = view.bounds
        view.layer.insertSublayer(drawLayer, atIndex: 0)
        
        //2.设置预览图层－设定图层大小
        previewLayer.frame = view.bounds
        //设置图层填充模式
        previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        //将图层插入到当前图层
        view.layer.insertSublayer(previewLayer, atIndex: 0)
    }
    
    /// 设置会话
    func setupSession(){
        //1.判断能否添加输入设备
        if !session.canAddInput(inputDevice){
            print("无法添加输入设备")
            return
        }
        //2.判断能否添加输出数据
        if !session.canAddOutput(outputData) {
            print("无法添加输出数据")
            return
        }
        //3.添加设备
        session.addInput(inputDevice)
        session.addOutput(outputData)
        //4.设置检测数据类型,检测所有支持的可以数据类型
        outputData.metadataObjectTypes = outputData.availableMetadataObjectTypes
        print("后 \(outputData.availableMetadataObjectTypes)")

        //5.设置数据的代理
        outputData.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
    }
    
    // MARK:- 懒加载
    ///绘图图层
    lazy var drawLayer: CALayer = CALayer()
    
    ///预览视图 - 依赖与session的
    lazy var previewLayer: AVCaptureVideoPreviewLayer = {
          return  AVCaptureVideoPreviewLayer(session: self.session)
    }()
    
    ///session 输入设备与输出数据的桥梁
    lazy var session: AVCaptureSession = {
        return AVCaptureSession()
    }()
    ///输入设备
    lazy var inputDevice: AVCaptureDeviceInput? = {
        //获取摄像头设备
//        let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeAudio)
        let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        
        do{
            return try AVCaptureDeviceInput(device: device)
        }catch{
            print(error)
            return nil
        }
    }()
    ///输出数据
    lazy var outputData: AVCaptureMetadataOutput = {
        return AVCaptureMetadataOutput()
    }()
    
    ///绘制变现形状
    func drawCorners(codeObject: AVMetadataMachineReadableCodeObject){
        // 可以做动画绘图的,专门在图层中画图
        let layer = CAShapeLayer()
        layer.lineWidth = 4
        layer.strokeColor = UIColor.greenColor().CGColor
        layer.fillColor = UIColor.clearColor().CGColor
        //coreObejct 的 cornes 是一个 包含 CFDictionaries 的 NSArray
        layer.path = createPath(codeObject.corners).CGPath
        drawLayer.addSublayer(layer)
    }
    
    ///创建一个绘制路径
    func createPath(corners: NSArray) ->UIBezierPath{
        let path = UIBezierPath()
        //定义一个point结构体
        var point = CGPoint()
        var index = 0
        //拿到第 0 个点
        CGPointMakeWithDictionaryRepresentation(corners[index++] as! CFDictionary, &point)
        //移动到第0个点
        path.moveToPoint(point)
        //遍历剩余的点
        while index < corners.count {
            CGPointMakeWithDictionaryRepresentation(corners[index++] as! CFDictionary, &point)
            //添加路线
            path.addLineToPoint(point)
        }
        //关闭路径
        path.closePath()
        return path
    }
    
    ///清空绘图图层
    func clearDrawLaer(){
        //如果drawLayer上没有子图片  直接返回
        if drawLayer.sublayers == nil {
            return
        }
        
        for subLaer in drawLayer.sublayers! {
            subLaer.removeFromSuperlayer()
        }
    }
    
    ///MARK : -AVCaptureMetadataOutputObjectsDelegate
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
        
        //清除上一次扫描绘制的图层
        clearDrawLaer()
        
        for object in metadataObjects {
            //判断识别对象类型
            if object is AVMetadataMachineReadableCodeObject {
                //转换数据类型
                let codeObject = previewLayer.transformedMetadataObjectForMetadataObject(object as! AVMetadataObject) as! AVMetadataMachineReadableCodeObject
                drawCorners(codeObject)
                //显示扫描结果
                resultLabel.text = codeObject.stringValue
            }
        }
    }
}
